/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package org.ipti.br.tag.bean;

import org.ipti.br.tag.bo.AddInfoPersonageBO;
import org.ipti.br.tag.bo.AdditionalInfoBO;
import org.ipti.br.tag.bo.AdditionalInfoTypeBO;
import org.ipti.br.tag.bo.AddressBO;
import org.ipti.br.tag.bo.JuridicBO;
import org.ipti.br.tag.bo.NeighborhoodBO;
import org.ipti.br.tag.bo.OrganizationBO;
import org.ipti.br.tag.bo.PeriodBO;
import org.ipti.br.tag.bo.StreetBO;
import org.ipti.br.tag.bo.UnityBO;
import org.ipti.br.tag.bo.ZipcodeBO;
import org.ipti.br.tag.entity.AdditionalInfo;
import org.ipti.br.tag.entity.AdditionalInfoType;
import org.ipti.br.tag.entity.Address;
import org.ipti.br.tag.entity.Juridic;
import org.ipti.br.tag.entity.Neighborhood;
import org.ipti.br.tag.entity.Organization;
import org.ipti.br.tag.entity.Period;
import org.ipti.br.tag.entity.Street;
import org.ipti.br.tag.entity.Unity;
import org.ipti.br.tag.entity.Zipcode;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import javax.inject.Inject;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.ViewScoped;
import javax.faces.model.SelectItem;

/**
 *
 * @author root
 */
@ManagedBean(name = "unityRegistration")
@ViewScoped
public class UnityRegistrationBean extends AppBaseBean {

    @Inject
    private AddInfoPersonageBO addInfoPersonageBO;
    @Inject
    private AdditionalInfoBO additionalInfoBO;
    @Inject
    private AdditionalInfoTypeBO additionalInfoTypeBO;
    @Inject
    private AddressBO addressBO;
    @Inject
    private JuridicBO juridicBO;
    @Inject
    private OrganizationBO organizationBO;
    @Inject
    private PeriodBO periodBO;
    @Inject
    private UnityBO unityBO;
    @Inject
    private ZipcodeBO zipcodeBO;
    @Inject
    private NeighborhoodBO neighborhoodBO;
    @Inject
    private StreetBO streetBO;
    @ManagedProperty("#{sessionBean}")
    private SessionBean sessionBean;
    private Address address;
    private Juridic juridic;
    private Unity unity;
    private int organizationType;
    private Long addInfoTypeID;
    private Long organizationID;
    private Long periodID;
    private Long unityFatherID;
    private String additionalInfo;
    private String capacity;
    private String neighborhood;
    private String organizationFather;
    private boolean needJuridic;
    private boolean success;
    private boolean deactivatedIsNull;
    private boolean neededSetFather = true;
    private String cep;
    private Zipcode zipcode;
    private String street;
    private boolean showAddress = false;
    private List<AdditionalInfo> additionalInfoList;
    private List<SelectItem> additionalInfoTypeList;
    private List<SelectItem> periodList;
    private List<SelectItem> unitiesFather;

    /** Creates a new instance of UnityRegistrationBean */
    public UnityRegistrationBean() {
    }

    public void searchCEP() {
        neighborhood = "";
        street = "";
        zipcode = zipcodeBO.searchByCode(Integer.parseInt(cep));
        if (zipcode == null) {
            showAddress = false;
            addInfoMessage("unityRegistrationForm:unityRegistrationView:cep", "CEP não cadastrado.", null);
        } else {
            if (zipcode.getNeighborhood() != null) {
                neighborhood = zipcode.getNeighborhood().getName();
            }
            if (zipcode.getStreet() != null) {
                street = zipcode.getStreet().getName();
            }
            showAddress = true;
        }
    }

    public List<String> neighborhoodComplete(String query) {
        return neighborhoodBO.neighborhoodList(query, zipcode.getCity());
    }

    public List<String> streetComplete(String query) {
        return streetBO.streetList(query, zipcode.getCity());
    }

    public void clean() {
        address = null;
        juridic = null;
        unity = null;
        deactivatedIsNull = true;
        showAddress = false;
        cep = null;
        zipcode = null;
        additionalInfoList = null;
    }

    public void initialize() {
        showAddress = false;
        deactivatedIsNull = true;
        unity = new Unity();
        unity.setActivated(Calendar.getInstance());
        unity.setDeactivated(Calendar.getInstance());
        loadNeedJuridic();
        loadUnitiesFather();
        loadAddInfoList();
        loadAddInfoTypeList();
        loadPeriodList();
        if (needJuridic) {
            address = new Address();
            juridic = new Juridic();
            juridic.setBirthday(Calendar.getInstance());
        }
        organizationFather = getOrganizationBO().find(organizationID).getOrg_father().getName();
        success = false;
    }

    public String getOrganizationName() {
        return getOrganizationBO().find(organizationID).getName();
    }

    public void save() {
        if (validateDates() & validateBirthday() & validateZipcode()) {
            if (needJuridic) {
                address.setZipcode(zipcode);
                Neighborhood neighborhoodAux = neighborhoodBO.searchByNameCity(neighborhood, zipcode.getCity().getId());
                Street streetAux = streetBO.searchByNameCity(street, zipcode.getCity().getId());

                if (neighborhoodAux == null) {
                    neighborhoodAux = new Neighborhood(neighborhood, zipcode.getCity());
                    neighborhoodBO.create(neighborhoodAux);
                }
                if (streetAux == null) {
                    streetAux = new Street(street, zipcode.getCity());
                    streetBO.create(streetAux);
                }

                address.setNeighborhood(neighborhoodAux);
                address.setStreet(streetAux);

                Long addressID = addressBO.searchExactAddress(address);

                if (addressID == null || addressID.equals(0L)) {
                    addressBO.create(address);
                } else {
                    address.setId(addressID);
                }

                juridic.setAddress(address);
                juridicBO.create(juridic);

                for (AdditionalInfo ai : additionalInfoList) {
                    ai.setPerson(juridic);
                    getAdditionalInfoBO().create(ai);
                }

                unity.setPerson(juridic);
            }

            if (deactivatedIsNull) {
                unity.setDeactivated(null);
            }

            Period period = new Period();
            period.setId(periodID);
            unity.setPeriod(period);
            Organization organization = new Organization();
            organization.setId(organizationID);
            Unity unityFather = new Unity();
            unityFather.setId(unityFatherID);
            unity.setUnityFather(unityFather);
            unity.setOrganization(organization);
            if(getUnityBO().find(unity) != null){
                 addErrorMessage("unityRegistrationForm:unityRegistrationView", "Unidade existente.", null);
            }
            else{
                getUnityBO().create(unity);

                clean();
                initialize();
                addInfoMessage("unityRegistrationForm:unityRegistrationView", "Cadastro realizado com sucesso.", null);
            }
        }

    }

    public boolean validateZipcode() {
        if (zipcode != null || !needJuridic) {
            return true;
        } else {
            addErrorMessage("unityRegistrationForm:unityRegistrationView", "'Endereço' é obrigatório", null);
            return false;
        }
    }

    public boolean validateDates() {
        if (deactivatedIsNull || unity.getActivated().getTime().before(unity.getDeactivated().getTime())) {
            return true;
        } else {
            addErrorMessage("unityRegistrationForm:unityRegistrationView", "'Desativação' deve ser após 'Ativação'", null);
            return false;
        }
    }

    public boolean validateBirthday() {
        if (needJuridic) {
            if (juridic.getBirthday().before(Calendar.getInstance())) {
                return true;
            } else {
                addErrorMessage("unityRegistrationForm", "'Data de Fundação' deve ser anterior à data atual", null);
                return false;
            }
        } else {
            return true;
        }
    }

    public void loadAddInfoList() {
        additionalInfoList = new ArrayList<AdditionalInfo>();
        for (AdditionalInfoType ait : getAddInfoPersonageBO().findAddInfoTypesWithoutPersonage()) {
            AdditionalInfo ai = new AdditionalInfo();
            ai.setAdditionalInfoType(ait);
            additionalInfoList.add(ai);
        }
    }

    public void loadAddInfoTypeList() {
        additionalInfoTypeList = new ArrayList<SelectItem>();
        additionalInfoTypeList.add(new SelectItem(0L, "Selecione um tipo"));
        for (AdditionalInfoType ait : getAdditionalInfoTypeBO().findAllOrder()) {
            additionalInfoTypeList.add(new SelectItem(ait.getId(), ait.getAcronym()));
        }
    }

    public void loadNeedJuridic() {
        if (organizationType == 0) {
            needJuridic = false;
        } else {
            needJuridic = true;
        }
    }

    public void loadPeriodList() {
        periodList = new ArrayList<SelectItem>();
        for (Period p : getPeriodBO().findAllOrder()) {
            periodList.add(new SelectItem(p.getId(), p.getDescription()));
        }
    }

    public void loadUnitiesFather() {
        unitiesFather = new ArrayList<SelectItem>();
        unitiesFather.add(new SelectItem(null, "Selecione uma unidade"));
        List<Unity> unities = getUnityBO().unityChildrenPerOrganization(sessionBean.getLoggedActor().getUnity(),
                getOrganizationBO().find(organizationID).getOrg_father());
        if(unities.size() == 1){
            unityFatherID = unities.get(0).getId();
            neededSetFather = false;
            return;
        }
        for (Unity u : unities) {
            unitiesFather.add(new SelectItem(u.getId(), u.getName()));
        }
    }

    public boolean checkUnity(Unity unityToFind, Unity userUnity) {
        boolean a = false;

        if (userUnity != null) {
            if (userUnity.getId() == unityToFind.getId()) {
                a = true;
            } else {
                for (Unity u : getUnityBO().getUnityChildren(userUnity.getId())) {
                    if (checkUnity(unityToFind, u)) {
                        a = true;
                        break;
                    }
                }
            }
        }

        return a;
    }

    /*
     * Getters and Setters
     */
    public AddInfoPersonageBO getAddInfoPersonageBO() {
        return addInfoPersonageBO;
    }

    public void setAddInfoPersonageBO(AddInfoPersonageBO addInfoPersonageBO) {
        this.addInfoPersonageBO = addInfoPersonageBO;
    }

    public AdditionalInfoBO getAdditionalInfoBO() {
        return additionalInfoBO;
    }

    public void setAdditionalInfoBO(AdditionalInfoBO additionalInfoBO) {
        this.additionalInfoBO = additionalInfoBO;
    }

    public AdditionalInfoTypeBO getAdditionalInfoTypeBO() {
        return additionalInfoTypeBO;
    }

    public void setAdditionalInfoTypeBO(AdditionalInfoTypeBO additionalInfoTypeBO) {
        this.additionalInfoTypeBO = additionalInfoTypeBO;
    }

    public AddressBO getAddressBO() {
        return addressBO;
    }

    public void setAddressBO(AddressBO addressBO) {
        this.addressBO = addressBO;
    }

    public JuridicBO getJuridicBO() {
        return juridicBO;
    }

    public void setJuridicBO(JuridicBO juridicBO) {
        this.juridicBO = juridicBO;
    }

    public PeriodBO getPeriodBO() {
        return periodBO;
    }

    public void setPeriodBO(PeriodBO periodBO) {
        this.periodBO = periodBO;
    }

    public UnityBO getUnityBO() {
        return unityBO;
    }

    public void setUnityBO(UnityBO unityBO) {
        this.unityBO = unityBO;
    }

    public SessionBean getSessionBean() {
        return sessionBean;
    }

    public void setSessionBean(SessionBean sessionBean) {
        this.sessionBean = sessionBean;
    }

    public Address getAddress() {
        if (address == null) {
            address = new Address();
        }
        return address;
    }

    public void setAddress(Address address) {
        this.address = address;
    }

    public Juridic getJuridic() {
        return juridic;
    }

    public void setJuridic(Juridic juridic) {
        this.juridic = juridic;
    }

    public Unity getUnity() {
        return unity;
    }

    public void setUnity(Unity unity) {
        this.unity = unity;
    }

    public int getOrganizationType() {
        return organizationType;
    }

    public void setOrganizationType(int organizationType) {
        this.organizationType = organizationType;
    }

    public Long getAddInfoTypeID() {
        return addInfoTypeID;
    }

    public void setAddInfoTypeID(Long addInfoTypeID) {
        this.addInfoTypeID = addInfoTypeID;
    }

    public Long getOrganizationID() {
        return organizationID;
    }

    public void setOrganizationID(Long organizationID) {
        this.organizationID = organizationID;
    }

    public Long getPeriodID() {
        return periodID;
    }

    public void setPeriodID(Long periodID) {
        this.periodID = periodID;
    }

    public String getAdditionalInfo() {
        return additionalInfo;
    }

    public void setAdditionalInfo(String additionalInfo) {
        this.additionalInfo = additionalInfo;
    }

    public String getCapacity() {
        return capacity;
    }

    public void setCapacity(String capacity) {
        this.capacity = capacity;
    }

    public String getNeighborhood() {
        return neighborhood;
    }

    public void setNeighborhood(String neighborhood) {
        this.neighborhood = neighborhood;
    }

    public String getOrganizationFather() {
        return organizationFather;
    }

    public void setOrganizationFather(String organizationFather) {
        this.organizationFather = organizationFather;
    }

    public boolean isNeedJuridic() {
        return needJuridic;
    }

    public void setNeedJuridic(boolean needJuridic) {
        this.needJuridic = needJuridic;
    }

    public List<AdditionalInfo> getAdditionalInfoList() {
        if (additionalInfoList == null) {
            loadAddInfoList();
        }
        return additionalInfoList;
    }

    public void setAdditionalInfoList(List<AdditionalInfo> additionalInfoList) {
        this.additionalInfoList = additionalInfoList;
    }

    public List<SelectItem> getAdditionalInfoTypeList() {
        if (additionalInfoTypeList == null) {
            loadAddInfoTypeList();
        }
        return additionalInfoTypeList;
    }

    public void setAdditionalInfoTypeList(List<SelectItem> additionalInfoTypeList) {
        this.additionalInfoTypeList = additionalInfoTypeList;
    }

    public List<SelectItem> getPeriodList() {
        if (periodList == null) {
            loadPeriodList();
        }
        return periodList;
    }

    public void setPeriodList(List<SelectItem> periodList) {
        this.periodList = periodList;
    }

    public List<SelectItem> getUnitiesFather() {
        if (unitiesFather == null) {
            loadUnitiesFather();
        }
        return unitiesFather;
    }

    public void setUnitiesFather(List<SelectItem> unitiesFather) {
        this.unitiesFather = unitiesFather;
    }

    public OrganizationBO getOrganizationBO() {
        return organizationBO;
    }

    public void setOrganizationBO(OrganizationBO organizationBO) {
        this.organizationBO = organizationBO;
    }

    public Long getUnityFatherID() {
        return unityFatherID;
    }

    public void setUnityFatherID(Long unityFatherID) {
        this.unityFatherID = unityFatherID;
    }

    public boolean isSuccess() {
        return success;
    }

    public void setSuccess(boolean success) {
        this.success = success;
    }

    public boolean isDeactivatedIsNull() {
        return deactivatedIsNull;
    }

    public void setDeactivatedIsNull(boolean deactivatedIsNull) {
        this.deactivatedIsNull = deactivatedIsNull;
    }

    public String getCep() {
        return cep;
    }

    public void setCep(String cep) {
        this.cep = cep;
    }

    public boolean isShowAddress() {
        return showAddress;
    }

    public void setShowAddress(boolean showAddress) {
        this.showAddress = showAddress;
    }

    public String getStreet() {
        return street;
    }

    public void setStreet(String street) {
        this.street = street;
    }

    public Zipcode getZipcode() {
        return zipcode;
    }

    public void setZipcode(Zipcode zipcode) {
        this.zipcode = zipcode;
    }

    public boolean isNeededSetFather() {
        return neededSetFather;
    }

    public void setNeededSetFather(boolean neededSetFather) {
        this.neededSetFather = neededSetFather;
    }
}
